﻿using Domain.Entity;
using DtoFw;
using DtoFw.Enum;
using DtoFw.Query;
using Repository;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Microsoft.AspNetCore.Hosting;

namespace Service
{
    public class DbBakService
    {
        private readonly DbbakRepository _dbBakRepository;
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly MainConfigRepository _mainConfigRepository;
        public DbBakService(DbbakRepository dbBakRepository, IHostingEnvironment hostingEnvironment, MainConfigRepository mainConfigRepository)
        {
            this._dbBakRepository = dbBakRepository;
            this._hostingEnvironment = hostingEnvironment;
            this._mainConfigRepository = mainConfigRepository; 
        }

        /// <summary>
        /// 查询备份记录
        /// </summary>
        public BaseGenericResult<Pager<DbbakEntity>> QueryBakList(LogQuery query)
        {
            int total = 0;
            var wh = "";
            if (query.StartDate.HasValue)
                wh += $" AND CreateTime>='{query.StartDate.Value.ToString("yyyy-MM-dd")}' ";
            else if (query.EndDate.HasValue)
                wh += $" AND CreateTime<='{query.EndDate.Value.ToString("yyyy-MM-dd")} 23:59:59' ";
            var sql = $@" select * 
                            from tb_dbbak 
                           where IsDeleted=0 {wh}
                           order by id desc  ";
            var r1 = _dbBakRepository.GetDb().SqlQueryable<DbbakEntity>(sql).ToPageList(query.Page, query.PageSize, ref total);

            return new BaseGenericResult<Pager<DbbakEntity>>() { Success = true, Code = EnumReturnCode.Success, Data = new Pager<DbbakEntity>() { Data = r1, TotalCount = total } };
        }
        public DbbakEntity AddDbBak(string path)
        {
            var entity = new DbbakEntity()
            {
                Path = path,
                Status = 0, 
                CreateTime = DateTime.Now,
                Creator = "sys",
                CreatorId = 0,
                Modifyer = "sys",
                ModifyerId = 0,
                ModifyerTime = DateTime.Now
            };
            entity.Id = _dbBakRepository.Insert(entity);
            return entity;
        }
        public BaseResult Delete(BaseQuery reqDto)
        {
            var lstRet = new List<object>();
            foreach (var _id in reqDto.Ids)
            {
                var inf = this._dbBakRepository.Query(v => v.Id == _id).FirstOrDefault();
                inf.IsDeleted = true;
                inf.Modifyer = reqDto.UserName;
                inf.ModifyerId = reqDto.UserId;
                inf.ModifyerTime = DateTime.Now;
                this._dbBakRepository.Update(inf);
            }
            return BaseResult.Succeed();
        }
        public void Update(DbbakEntity t)
        {
            this._dbBakRepository.Update(t);
        }



        /// <summary>
        /// 数据库备份任务
        /// </summary>
        public bool DbBakTask()
        {
            var r1 = _mainConfigRepository.Query(new BaseQuery(), t => t.Where(m => m.CategoryCode == EnumClass.DbBakConfig && m.Class == EnumClass.DbBakConfig)).First();
            if (r1 != null)
            {
                if (r1 != null && !string.IsNullOrEmpty(r1.Content) && r1.Content.StartsWith("{"))
                {
                    //备份时间计划
                    var ty = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(r1.Content, new { wk = new List<string>(), hour = 0 });
                    if (ty != null)
                    {
                        var now = DateTime.Now;
                        var wn = new string[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }[(int)now.DayOfWeek];
                        if (ty.wk != null && ty.wk.Contains(wn))
                        {
                            if (now.Hour == ty.hour || (ty.hour > 0 && now.Hour % ty.hour == 0))
                            {
                                RunDbBakCmd();
                            }
                        }
                    }
                }
            }
            
            return true;
        }
        public void RunDbBakCmd()
        {
            try
            {
                var kLs = Cache.GlobalData.DbConnect.Mysql.Split(';');
                var database = kLs.SingleOrDefault(v => v.Contains("database=")).Replace("database=", "");
                var root = kLs.SingleOrDefault(v => v.Contains("uid=")).Replace("uid=", "");
                var pwd = kLs.SingleOrDefault(v => v.Contains("pwd=")).Replace("pwd=", "");
                var path = $"/dbbak/{database}_{DateTime.Now.ToString("yyyyMMddHHmm")}_bak.sql";
                var savePath = _hostingEnvironment.ContentRootPath.Replace("\\", "/") + path;

                var cmd = $"mysqldump -u{root} -p{pwd} --databases {database} --skip-opt --skip-add-locks --single-transaction --set-gtid-purged=off --max_allowed_packet=512M > " + savePath;
                System.Diagnostics.Process p = new System.Diagnostics.Process();
                p.StartInfo.Verb = "runas";
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.CreateNoWindow = true;
                p.Start();
                Console.WriteLine(cmd);
                //备份命令
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.AutoFlush = true;
                //退出cmd
                p.StandardInput.WriteLine("exit");
                string results = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                //存放数据
                var dbBak = AddDbBak(Cache.GlobalData.EvidenceInfo.BaseImgUrl.Replace("/img/", "") + path);
                //修改备份记录状态
                dbBak.Status = 1;
                dbBak.ModifyerTime = DateTime.Now;
                _dbBakRepository.Update(dbBak);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}
